#include "chatserver.hpp"
#include  "json.hpp"
#include "chatservice.hpp"

#include <functional>
#include<string>
using namespace std;
using namespace placeholders;
using json = nlohmann::json; //起了个更多的名称 

ChatServer::ChatServer(EventLoop *loop,
                       const InetAddress &listenAddr,
                       const string &nameArg)
    : _server(loop, listenAddr, nameArg), _loop(loop)
{
    // 当相应事件发生，就会调用对应的回调函数
    // 给服务器注册用户链接的创建和断开回调
    _server.setConnectionCallback(bind(&ChatServer::onConnection, this, _1));
    //_1占位符，指onConnection的第一个参数

    // 给服务器注册用户读写事件回调
    _server.setMessageCallback(bind(&ChatServer::onMessage, this, _1, _2, _3));

    // 设置服务器端的线程数量 , 一个IO线程，　３个工作线程　　－－》与CPU核数相近
    _server.setThreadNum(4);
}

// 启动服务
void ChatServer::start()
{
    _server.start();
}

// 专门处理用户的连接的创建和断开 epoll listenfd accpet
void ChatServer::onConnection(const TcpConnectionPtr &conn)
{
    //客户端断开链接
    if(!conn->connected())
    {
        ChatService::instance()->clientCloseException(conn);//客户端异常关闭了
        conn->shutdown();
    }
}

// 专门处理用户的读写事件
void ChatServer::onMessage(const TcpConnectionPtr &conn, // 链接
                           Buffer *buffer,               // 缓冲区
                           Timestamp time)               // 接收到数据的事件信息
{
    string buf = buffer->retrieveAllAsString();
    //数据的反序列化
    json js = json::parse(buf);

    //达到的目的 ： 完全解耦  网络模块的代码和业务模块的代码

    //通过 js["msgid"] 获取 -》 业务handler -> conn js time
    auto msghandler =  ChatService::instance()->getHandler(js["msgid"].get<int>());
    
    //回调消息绑定好的事件处理器，来执行相应的业务处理
    // 完全解耦合了
    msghandler(conn,js,time);
}
